package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.basecontext.BaseContext;
import com.hmall.common.client.ItemClient;
import com.hmall.common.client.UserClient;
import com.hmall.common.dto.Address;
import com.hmall.common.dto.Item;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.OrderSubmit;
import com.hmall.order.service.IOrderService;
import com.hmall.order.service.OrderDetailService;
import com.hmall.order.service.OrderLogisticsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderLogisticsService orderLogisticsService;

    /**
     * 创建订单
     * @param orderSubmit 客户提交订单自定义接收数据类型
     * @return 订单id
     */
    @Transactional
    @Override
    public Long submit(OrderSubmit orderSubmit) {
        log.info("[订单微服务===>业务端处理，接收的信息：{}]",orderSubmit.toString());
        // 商品购买数量
        Integer num = orderSubmit.getNum();
        // 付款方式
        Integer paymentType = orderSubmit.getPaymentType();
        // 收货人地址
        Long addressId = orderSubmit.getAddressId();
        // 远程调用，根据收货人地址查询地址信息
        Address address = userClient.findAddressById(addressId);
        // 商品id
        Long itemId = orderSubmit.getItemId();
        // 远程调用，根据商品id查询商品信息
        // 这里报错了，经过商品微服务时用户id为null，但是上面经过用户微服务时为什么可以的，因为用户微服务没有对地址路径进行拦截啊
        // 微服务之间调用请求头不起作用，网关仅对外部访问时起作用，微服务之间参考微实战笔记
        // 取消商品微服务中的拦截器
        // 总结：远程同步调用问题，思路==>1.调用端参数；2.feign接口参数，路径；3.被调用方拦截器
        Item item = itemClient.findById(itemId);
        // 通过ThreadLocal查询用户id，远程调用查询用户信息
        Long userId = BaseContext.getCurrentId();
        log.info("[订单微服务===>业务端处理，从ThreadLocal中取出用户id：{}]",userId);

        // 创建对象 订单Order，订单详情OrderDetail，物流信息OrderLogistics
        Order order = new Order();
        OrderDetail orderDetail = new OrderDetail();
        OrderLogistics orderLogistics = new OrderLogistics();

        // 订单order存入信息并写入数据库
        // order.setId(IdWorker.getId());雪花算法生成订单id，直接使用注解方式@TableId(type = IdType.ASSIGN_ID)
        // 总金额：商品数量*商品单价
        order.setTotalFee(num*item.getPrice());
        order.setPaymentType(paymentType);
        order.setUserId(userId);
        order.setStatus(1); // 初始化支付状态为 1.未支付
        // order.setCreateTime(); 自动设置
        // order.setUpdateTime(); 自动设置
        // 暂时无法设置，忽略order.setPayTime();order.setConsignTime();order.setEndTime();order.setCloseTime();order.setCommentTime();
        this.save(order);

        // 订单详情OrderDetail存入信息并写入数据库
        // orderDetail.setId();雪花算法生成
        orderDetail.setOrderId(order.getId());
        orderDetail.setItemId(itemId);
        orderDetail.setNum(num);
        orderDetail.setName(item.getName()); //字段不匹配，更改或添加注解
        orderDetail.setPrice(item.getPrice());
        orderDetail.setSpec(item.getSpec());
        orderDetail.setImage(item.getImage());
        // orderDetail.setCreateTime(); 自动设置
        // orderDetail.setUpdateTime(); 自动设置
        orderDetailService.save(orderDetail);

        // 物流信息OrderLogistics存入信息并写入数据库
        orderLogistics.setOrderId(order.getId());
        BeanUtils.copyProperties(address,orderLogistics);
        // orderLogistics.setPhone(); 字段不匹配，更改，添加注解需要重新设置手机号码
        // orderLogistics.setLogisticsNumber();
        // orderLogistics.setLogisticsCompany();
        // orderLogistics.setCreateTime(); 自动设置
        // orderLogistics.setUpdateTime(); 自动设置
        orderLogisticsService.save(orderLogistics);

        // 扣减库存
        try {
            itemClient.updateStock(itemId,num);
        } catch (Exception e) {
            throw new RuntimeException("库存不足，请及时联系商家补充货源！");
        }

        return order.getId();
    }

    /**
     * 处理超时未处理订单
     */
    @Override
    public void closeOrder() {
        // 查询超时订单详情 5min
        // 不能用？=====>orderDetailService.getBaseMapper().queryTimeoutOrderDetail();
        List<OrderDetail> orderDetailList = orderDetailService.queryTimeoutOrderDetail();
        if (orderDetailList==null || orderDetailList.size()==0){
            return;
        }
        // 恢复库存
        for (OrderDetail orderDetail : orderDetailList) {
            itemClient.updateStock(orderDetail.getItemId(), -orderDetail.getNum());
        }
         // 收集订单id
        List<Long> orderIdList = orderDetailList.stream().map(OrderDetail::getOrderId).collect(Collectors.toList());

        // 取消订单
        LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Order::getStatus, 5);
        updateWrapper.set(Order::getCloseTime, new Date());
        updateWrapper.in(Order::getId, orderIdList);
        this.update(updateWrapper);
        log.info("[定时器执行===>取消超时订单]");
    }
}
